package xyz.mumuwei.youthcourseserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import xyz.mumuwei.youthcourseserver.common.dto.PageDto;
import xyz.mumuwei.youthcourseserver.common.lang.Result;
import xyz.mumuwei.youthcourseserver.job.SendWechatReserveMessageJob;
import xyz.mumuwei.youthcourseserver.mapper.CourseMapper;
import xyz.mumuwei.youthcourseserver.mapper.StudentExperienceMapper;
import xyz.mumuwei.youthcourseserver.mapper.UserInfoMapper;
import xyz.mumuwei.youthcourseserver.mapper.UserMapper;
import xyz.mumuwei.youthcourseserver.pojo.*;
import xyz.mumuwei.youthcourseserver.service.StudentExperienceService;
import xyz.mumuwei.youthcourseserver.utils.QuartzUtil;
import xyz.mumuwei.youthcourseserver.utils.TimeUtil;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author mumuwei
 * @since 2022-02-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StudentExperienceServiceImpl extends ServiceImpl<StudentExperienceMapper, StudentExperience> implements StudentExperienceService {

    final StudentExperienceMapper studentMapper;
    final UserInfoMapper infoMapper;
    final CourseMapper courseMapper;
    final UserMapper userMapper;

    /**
     * 学生预约 体验课程
     *
     * @param courseId 课程id
     * @param uid 用户账户id
     * @return 预约结果
     */
    @Override
    public Result reserveCourseByStudent(Integer courseId, Integer uid) throws SchedulerException {
        StudentExperience experience = new StudentExperience();
        experience.setCourseId(courseId);
        // 设置学生id
        experience.setStudentId(getUserInfoId(uid));
        int insert = studentMapper.insert(experience);
        if (insert > 0) {
            // 预约后定时发送微信订阅消息
            User user = userMapper.selectById(uid);
            if(user.getOpenId() != null) {
                // 获取体验课时间
                Course course = courseMapper.getCourseById(courseId);
                if (course != null) {
                    // 设置数据
                    HashMap<String, Object> map = new HashMap<>(3);
                    map.put("courseId", courseId);
                    map.put("openId", user.getOpenId());
                    map.put("timeId", 0);

                    String experienceTime = course.getExperienceTime();
                    String jobName = uid + "" + courseId + experienceTime;

                    String time19 =
                            String.valueOf(
                                    Integer.parseInt(
                                            TimeUtil.getStartOfDay(
                                                    new Date(Long.parseLong(experienceTime + "000")))) - 5*60*60);
                    String time2 = String.valueOf(Long.parseLong(experienceTime)-2*60*60);

                    // 课程前日19点提醒一次
                    QuartzUtil.getInstance().addJob(SendWechatReserveMessageJob.class,
                            jobName + "19",
                            "classTimeMessage",
                            TimeUtil.dateFormat(time19,"ss mm kk dd MM ? yyyy"),
                            map);

                    // 课程当日提前2小时提醒
                    QuartzUtil.getInstance().addJob(SendWechatReserveMessageJob.class,
                            jobName + "2",
                            "classTimeMessage",
                            TimeUtil.dateFormat(time2, "0 0 kk dd MM ? yyyy"),
                            map);
                }
            }

            return Result.success("预约成功！请按时参加体验课程！");
        }
        return Result.fail("预约失败！");
    }

    /**
     * 根据学生账户id 和 课程id 查询学生是否预约该课程
     *
     * @param courseId 课程id
     * @param uid      学生账户Id
     * @return 查询结果
     */
    @Override
    public Result checkReserveByCourseId(Integer courseId, Integer uid) {
        Integer studentId = getUserInfoId(uid);
        if(studentId == null) {
            return Result.success(0);
        }
        List<StudentExperience> list = studentMapper
                .selectList(
                        new QueryWrapper<StudentExperience>()
                                .eq("course_id", courseId)
                                .eq("student_id", studentId)
                );
        return Result.success(list.size());
    }

    /**
     * 根据学生账户 Id 和 课程Id 删除体验预约
     *
     * @param courseId 课程id
     * @param uid      学生账户Id
     * @return 删除结果
     */
    @Override
    public Result deleteByCourseId(Integer courseId, Integer uid) throws SchedulerException {
        Integer studentId = getUserInfoId(uid);
        int delete = studentMapper.delete(
                new QueryWrapper<StudentExperience>()
                .eq("course_id", courseId)
                .eq("student_id", studentId)
        );
        if(delete > 0) {
            // 删除定时消息预约提醒
            Course course = courseMapper.getCourseById(courseId);
            if (course != null) {
                String experienceTime = course.getExperienceTime();
                String jobName = uid + "" + courseId + experienceTime;

                QuartzUtil.getInstance().deleteJob(jobName + "2", "classTimeMessage");
                QuartzUtil.getInstance().deleteJob(jobName + "19", "classTimeMessage");
            }
            return Result.success("取消预约成功！");
        }
        return Result.fail("取消预约失败！");
    }

    /**
     * 根据学生账户id 获取学生预约课程列表
     *
     * @param uid 账户id
     * @return 预约列表
     */
    @Override
    public Result getStudentExperienceList(Integer uid) {
        Integer studentId = getUserInfoId(uid);
        if (studentId != null) {
            List<StudentExperience> list = studentMapper.getStudentExperienceList(studentId);
            return Result.success(list);
        }
        return Result.fail("获取失败！");
    }

    /**
     * 根据课程id获取课程预约体验课列表（不分页）
     *
     * @param courseId 课程id
     * @return 预约列表
     */
    @Override
    public Result getExperienceListByCourseId(Integer courseId) {
        List<StudentExperience> list = studentMapper.getExperienceListByCourseId(courseId);
        return Result.success(list);
    }

    /**
     * 根据课程id获取课程预约体验课列表（分页）
     *
     * @param courseId 课程id
     * @param pageDto  分页参数
     * @return 预约列表
     */
    @Override
    public Result getExperiencePageByCourseId(Integer courseId, PageDto pageDto) {
        pageDto.setStart((pageDto.getCurrent()-1)*pageDto.getSize());
        pageDto.setEnd(pageDto.getCurrent()*pageDto.getSize());
        pageDto.setId(courseId);
        List<StudentExperience> page = studentMapper.getExperiencePageByCourseId(pageDto);
        Page<StudentExperience> experiencePage = new Page<>(pageDto.getCurrent(), pageDto.getSize());
        experiencePage.setRecords(page);
        if (page.size() <= 0) {
            experiencePage.setTotal(0);
            return Result.success(experiencePage);
        }
        if(!"".equals(pageDto.getKey())) {
            experiencePage.setTotal(studentMapper.selectCount(new QueryWrapper<StudentExperience>()
                    .eq("course_id", courseId)
                    .like("real_name", pageDto.getKey())
            ));
        } else {
            experiencePage.setTotal(studentMapper.selectCount(new QueryWrapper<StudentExperience>().eq("course_id", courseId)));
        }
        return Result.success(experiencePage);
    }

    /**
     * 根据用户账户 Id 获取学生信息 Id
     * @param uid 账户id
     * @return 用户信息 Id
     */
    private Integer getUserInfoId(Integer uid) {
        UserInfo userInfo = infoMapper.selectOne(
                new QueryWrapper<UserInfo>()
                        .eq("user_id", uid)
        );
        if(userInfo == null) {
            return null;
        }
        return userInfo.getId();
    }
}
